package yxy.banana.launcher;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;

import yxy.apple.logger.Logger;
import yxy.apple.util.RuntimeUtility;
import yxy.apple.util.RuntimeUtility.ShutdownHookable;

public abstract class Launcher<C extends Configuration> {
	public static String ApplicationName = "Noname";
	public static String ReleaseVersion = "0.0.0";
	public static String ReleaseDate = "20200101";
	public static String Slogan = " -= " + ApplicationName + " V" + ReleaseVersion + " Release " + ReleaseDate + " =-";
	protected static Logger logger = Logger.create(Launcher.class);

	private class Hooker implements ShutdownHookable {
		@Override
		public void shutting() {
			Launcher.this.shutdown();
		}
	}

	private static String LoadOutsideConfig() {
		String configInfo = null;
//XXX 屏蔽Lagos		
//		try {
//			ConfigChangeManager configChangeManager = new ConfigChangeManager();
//			configChangeManager.addSubcribe();
//			configInfo = Lagos.getInstance().load();
//		} catch (Exception e) {
//			logger.error("读取外部配置文件失败", e);
//			configInfo = null;
//		}
		return configInfo;
	}

	public void start(Class<C> configurationClass) {
		ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
		try {
			logger.info(Slogan);
			logger.info("正在启动...");
			logger.info("正在载入配置...");
			C configuration = null;
			String outsideConfig = LoadOutsideConfig();
			if (outsideConfig == null) {
				String filename = System.getProperty("user.dir") + "/config.json";
				logger.info("加载配置文件%s...", filename);
				configuration = JSONBeanConfiguration.load(filename, configurationClass);
			} else {
				logger.info("加载nacos配置\n%s", outsideConfig);
				configuration = JSONBeanConfiguration.load(JSONObject.parseObject(outsideConfig), configurationClass);
			}
			JSONBeanConfiguration.share(Configuration.SharedKey, configuration);

			logger.info("设置日志等级为%s...", configuration.LogLevel.name());
//			Logger.setLevel(configuration.LogLevel);
			Logger.setLevel(Logger.Level.All);
			logger.info("正在添加ShutdownHook服务...");
			RuntimeUtility.addShutdownHook(new Hooker());
			this.reactor().start(configuration);
			logger.info("%s服务器启动完成!", ApplicationName);
		} catch (Exception e) {
			logger.error(e);
			System.exit(5);
		}
	}

	private void shutdown() {
		logger.info("正在关闭%s...", ApplicationName);
		this.reactor().shutdown();
		logger.info("完成%s全部关闭工作，Bye!", ApplicationName);
	}

	protected abstract Reactable<C> reactor();

}
